package com.qire.common.utils;

import android.os.CountDownTimer;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 倒计时器构建器
 */
public class CountDownTimerBuilder {

    public static CustomCountDownTimer build(long millisInFuture, long countDownInterval) {
        return build(millisInFuture, countDownInterval, TimeUnit.MILLISECONDS);
    }

    public static CustomCountDownTimer build(long countDownDuration, long countDownInterval, TimeUnit timeUnit) {
        return new CustomCountDownTimer(countDownDuration, countDownInterval, timeUnit);
    }

    public static class CustomCountDownTimer extends CountDownTimer {

        private final TimeUnit timeUnit;
        private CountDownTimeAction tickCallBack;
        private CountDownTimeAction finishCallBack;

        private long countDownTime;

        public CustomCountDownTimer(long countDownDuration, long countDownInterval, TimeUnit timeUnit) {
            super(timeUnit.toMillis(countDownDuration), timeUnit.toMillis(countDownInterval));
            this.timeUnit = timeUnit;
            this.countDownTime = countDownDuration;
        }

        public CustomCountDownTimer addTickCallBack(CountDownTimeAction tickCallBack) {
            this.tickCallBack = this.tickCallBack == null ? tickCallBack : this.tickCallBack.andThen(tickCallBack);
            return this;
        }

        public CustomCountDownTimer addFinishCallBack(CountDownTimeAction finishCallBack){
            this.finishCallBack = this.finishCallBack == null ? finishCallBack : this.finishCallBack.andThen(finishCallBack);
            return this;
        }

        @Override
        public void onTick(long millisUntilFinished) {
            if(tickCallBack != null) {
                countDownTime = tickCallBack.apply(countDownTime, timeUnit);
            }
        }

        @Override
        public void onFinish() {
            if(finishCallBack != null) {
                finishCallBack.apply(countDownTime, timeUnit);
            }
        }
    }

    @FunctionalInterface
    public interface CountDownTimeAction {
        long apply(long countDownTime, TimeUnit timeUnit);

        default CountDownTimeAction compose(CountDownTimeAction before) {
            Objects.requireNonNull(before);
            return (countDownTime, timeUnit) -> apply(before.apply(countDownTime, timeUnit), timeUnit);
        }

        default CountDownTimeAction andThen(CountDownTimeAction after) {
            Objects.requireNonNull(after);
            return (countDownTime, timeUnit) -> after.apply(apply(countDownTime, timeUnit), timeUnit);
        }

        static CountDownTimeAction identity() {
            return (countDownTime, timeUnit) -> countDownTime;
        }
    }

}
